package com.drako.tdgdx.logic.turret;

import java.util.ArrayList;

import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.math.Vector2;
import com.drako.tdgdx.helper.GlobalHelper;
import com.drako.tdgdx.helper.MeshObject;
import com.drako.tdgdx.helper.TargetHelper;
import com.drako.tdgdx.logic.GameObject;
import com.drako.tdgdx.logic.IHazBuildable;
import com.drako.tdgdx.logic.IHazLogic;
import com.drako.tdgdx.logic.IHazRenderable;
import com.drako.tdgdx.logic.Player;
import com.drako.tdgdx.logic.creep.Creep;

public class Tower extends GameObject implements IHazLogic, IHazRenderable,IHazBuildable {
	private float range;
	protected DamageType damage;
	private int costs;
	protected int maxTargets;
	protected float upgradeMulti;
	protected int level;
	protected int maxLevel;
	public static final int STANDARD_TARGETS = 1;
	private ArrayList<Creep> targets;
	private MeshObject mesh;
	protected Player player;
	// Defines the percentage of refund when selling a turret
	public final static float REFUND_FACTOR = 0.8f;

	public Tower(float x, float y, float range, int costs, int maxTargets,int maxLevel, DamageType damage, Player player) {
		super(x, y);
		this.range = range;
		this.setCosts(costs);
		this.maxTargets = maxTargets;
		targets = new ArrayList<Creep>();
		setDamageType(damage);
		this.player = player;
		level = 1;
		this.maxLevel = maxLevel;
		mesh = new MeshObject(x, y, GlobalHelper.TILESIZE,GlobalHelper.TILESIZE, GlobalHelper.TILESIZE * 2, 0, 0, 255,255);

	}

	public Tower(float x, float y, float range, int costs, int maxLevel,DamageType damage, Player player) {
		this(x, y, range, costs, STANDARD_TARGETS, maxLevel, damage, player);

	}

	public void detectCreep() {
		Vector2 tmpV;
		float temp;
		float range2 = range * range;
		for (Creep c : TargetHelper.possibleTargets) {

			tmpV = new Vector2(c.getPosition());
			temp = tmpV.sub(this.getPosition()).len2();
			if (temp < range2) {
				addTarget(c);
			}
			if (temp > range2 && targets.contains(c)) {
				removeTarget(c);
			}
		}
	}

	// is called when distance to creep is below range
	public void addTarget(Creep c) {
		targets.add(c);
		c.setTargeted(c.getTargeted() + 1);
	}

	// is called when distance to creep above range and wasn't a target before

	public void removeTarget(Creep c) {
		targets.remove(c);
		c.setTargeted(c.getTargeted() - 1);
	}

	// clears targets and will give back a percentage of the costs
	public void sellTurret() {
		targets.clear();

	}

	public void setDamageType(DamageType damage) {
		this.damage = damage;
	}

	public void doShoot() {
		damage.shoot();
	}

	public void upgrade() {
		level++;
	}

	public int getLevel() {
		return level;
	}

	public int getMaxLevel() {
		return maxLevel;
	}

	public void setRange(float range) {
		this.range = range;
	}

	public float getRange() {
		return range;
	}

	@Override
	public void render(GL10 gl) {
		mesh.render(gl);

	}

	@Override
	public void update() {
		detectCreep();

	}

	public void setCosts(int costs) {
		this.costs = costs;
	}

	public int getCosts() {
		return costs;
	}

	public int getUpgradeCosts(){
		return  (int) (costs*level*upgradeMulti);
	}

	@Override
	public void build() {
		// TODO Auto-generated method stub
		
	}
}
